import { Annotation } from '@langchain/langgraph';
import { baseInputVars, ILLMModelChunk, LLMNode, SendMessageData } from '../../../core';

export class ImageCmdNode extends LLMNode {
    systemPrompt = `
    你是一个专业的AI绘画提示词工程师。你的唯一任务是根据用户的简短描述+设计大纲+参考图片，生成一个极度详尽、结构化、可直接用于文生图模型（如Stable Diffusion, Midjourney）的英文提示词（Prompt）。

    生成规则（你必须严格遵守）：
    1.  核心结构：生成的Prompt必须遵循以下顺序和结构：
        [主题描述], [细节与氛围描述], [风格与质量描述], [构图与镜头描述], [色彩与灯光描述], [文案要求], [参数指令]
    2.  内容要求：
        ◦   主题与细节：必须详尽描述主体（人物、物体）、动作、表情、场景背景。使用形容词和具体名词。
        ◦   风格与质量：必须指定艺术风格（如：photorealistic, anime, oil painting, 3D render）和质量关键词（如：masterpiece, best quality, ultra detailed, 4K）。
        ◦   构图与镜头：必须指定构图（如：full shot, close-up, symmetrical composition）、视角（如：eye-level view, from above）和镜头效果（如：deph of field, bokeh, sharp focus）。
        ◦   色彩与灯光：必须描述色彩基调（如：vibrant colors, pastel color palette）和灯光（如：cinematic lighting, soft light, studio lighting）。
        ◦   文案：如果用户要求添加文字，必须明确写出文字内容，并指定位置（如：text at the bottom, watermark at the corner）。
        ◦   参数：必须在最后指定比例，如：--ar 9:16 (for Midjourney) 或 Steps: 20, Sampler: Euler a, CFG scale: 7, Size: 512x768 (for Stable Diffusion)。默认使用 --ar 9:16。

    3.  语言：全程使用英文撰写提示词，这是文生图模型的最优语言。但理解用户的中文输入。
    4.  负面提示（可选但建议）：根据生成的内容，自动添加通用的负面提示词，如：--no blur, lowres, bad hands, text, error, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username。
    5. 图片里面使用到的文字请使用中文
    6. 如果用户没有特别指明输出图的比例，图像比例根据最适合当前场景的方式选取，有： --ar 9:16, --ar 16:9, --ar 4:5, --ar 5:4, --ar 1:1

    ---

    用户输入：
    {{user_input}}

    你的输出（直接且仅输出生成的Prompt）：

    示例演示：

    用户输入：
    需要一张咖啡店教师节开业海报，一个穿黑色女仆装的长发甜美女孩，正面微笑，拿着咖啡，背景是咖啡店门前景深虚化。比例9:16，底部文字“教师节开业大酬宾，全场8折”。

    你的输出（AI生成的文生图指令）：
    A beautiful, sweet-looking long-haired woman wearing a classic black maid costume, full body shot, smiling at the viewer, holding a cup of coffee in her right hand, standing in front of a cozy coffee shop entrance, photorealistic, masterpiece, best quality, ultra-detailed, sharp focus, cinematic lighting, bokeh background, depth of field, vibrant and warm color palette, text at the bottom that reads "教师节开业大酬宾，全场8折", symmetrical composition, eye-level view --no blur, lowres, bad hands, error, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username

    ** 仅仅输出最终的Prompt，不要输出任何额外的解释或信息。 **
    ** 输出字符控制在800 以内 **
    ** 不要包含国旗等敏感词汇 **
    ** 不要包含二维码 **
    `;
    name = "ImageCmdNode";
    protected withOutPromptFormat: boolean = true;
    inputVars = Annotation.Root({
        ...baseInputVars.spec,
        outline: Annotation<string>,
        imageExt: Annotation<string>,
        imageSize: Annotation<string>,

        brandInfo: Annotation<string>,
        promotionInfo: Annotation<string>,
        purpose: Annotation<string>,
        stylePreference: Annotation<string>,
        highlight: Annotation<string>
    });

    outputVars = Annotation.Root({
        imageCmd: Annotation<string>,
        ImageCmdNodeResult: Annotation<string>,
    });

    protected OnModelStreamOut(chunk: ILLMModelChunk): void {
        this.OnMessage?.(this, new SendMessageData(this.inputVars.State.convID, this.name, "chat_node", chunk));
    }

    protected OnRunBegin(): void {
        this.OnMessage?.(this, new SendMessageData(this.inputVars.State.convID, this.name, "chat_node_title", { text: "正在生成图片结构..." }));
    }

    protected OnRunEnd(): void {
        this.OnMessage?.(this, new SendMessageData(this.inputVars.State.convID, this.name, "chat_node_title", { text: "完成图片结构生成！" }));
    }
    async Run() {
        this.userMessages = [
            `
##设计大纲: ${this.inputVars.State.outline}
##参考图片：${this.inputVars.State.imageExt}
##输出图片尺寸：${this.inputVars.State.imageSize}

##品牌信息：${this.inputVars.State.brandInfo || "无"}
##活动内容：${this.inputVars.State.promotionInfo || "无"}
##海报用途：${this.inputVars.State.purpose}
##风格偏好：${this.inputVars.State.stylePreference}
##重点突出：${this.inputVars.State.highlight}

##其他要求: ${this.inputVars.State.userInput}
                `
        ]

        await super.Run();
        this.outputVars.State.imageCmd = this.outputVars.State.ImageCmdNodeResult;

        return this.outputVars.State;
    }
}